package cate.game.fight.msg;


import cate.common.table.d.GDFight;
import cate.common.table.d.GDFunc;
import cate.common.table.fight.test.FightTestRow;
import cate.game.GameBody;
import cate.game.client.ClientContext;
import cate.game.client.msg.ClientMsg;
import cate.game.client.msg.MsgConfig;
import cate.game.client.msg.MsgInput;
import cate.game.client.msg.id.MsgIdBFight;
import cate.game.fight.test.TestFightCtx;
import cate.game.play.part.FightSide;
import cate.game.play.proce.play.PlayPO;
import cate.game.play.vo.FightStatVO;
import cate.game.play.vo.PlaySideVO;
import cate.game.play.vo.TeamVSVO;
import cate.game.role.Role;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;

@ClientMsg(title = "战斗测试 の 请求")
public class FightTestReq implements MsgInput {

    @NoteField("战斗测试ID【A方】")
    public int idA;

    @NoteField("战斗测试ID【B方】")
    public int idB;

    @NoteField("模拟次数")
    public int num = 1;

    @Override
    public void execute(GameBody game, ClientContext cc) {
        Role role = cc.getRole();
        FightSide a = getSide(role, GDFight.Team.A, idA);
        if (a == null) {
            role.getGame().notice.message(role, "a方阵容有问题");
            return;
        }
        FightSide b = getSide(role, GDFight.Team.B, idB);
        if (b == null) {
            role.getGame().notice.message(role, "b方阵容有问题");
            return;
        }
        b.ps.hs.forEach(f -> f.hero.uid += "_cp");
        b.ft.getAllHero().forEach(f -> f.uid += "_cp");
        if (num <= 1) {
            EcResult<PlayPO> r = role.getGame().play.startBySystem(new TestFightCtx(), a, b);
            if (r.ok()) {
                role.getCc().sendNow(new FightPlayResp(GDFunc.FIGHT_TEST, r.data));
            } else {
                role.getGame().notice.message(role, r);
            }
        } else {
            FightTestResultResp resp = new FightTestResultResp();
            resp.a = new PlaySideVO().read(a.ps);
            resp.b = new PlaySideVO().read(b.ps);
            role.getGame().notice.message(role, "战斗模拟中！请稍后");
            long start = System.currentTimeMillis();

            if (this.num > 1000) {
                this.num = 1000;
            }
            for (int i = 1; i <= this.num ; i++) {
                EcResult<PlayPO> r = role.getGame().play.startBySystem(new TestFightCtx(), a, b);
                if (r.ok()) {
                    PlayPO play = r.data;
                    if (resp.teamBegin == null) {
                        resp.teamBegin = new TeamVSVO().read(play.teamBegin);
                    }
                    switch (play.winner) {
                        case GDFight.Team.A:
                            resp.winATimes++;
                            break;
                        case GDFight.Team.B:
                            resp.winBTimes++;
                            break;
                        default:
                            break;
                    }
                    FightStatVO stat = new FightStatVO().read(play.teamEnd);
                    if (resp.stat == null) {
                        resp.stat = stat;
                    } else {
                        resp.stat.merge(stat);
                    }
                    resp.avgRound+=play.rounds.size();
                }
                a = getSide(role, GDFight.Team.A, idA);
                b = getSide(role, GDFight.Team.B, idB);
//                b.ps.hs.forEach(f -> f.hero.uid += "_cp");
//                b.ft.getHerosNoOut().forEach(f -> f.uid += "_cp");
            }
            resp.stat.divide(num);
            resp.avgRound/=num;
            long end = System.currentTimeMillis();
            role.getGame().notice.message(role, "战斗模拟耗时" + (end - start)  + "ms");
            role.sendNow(resp);
        }
    }




    @Override
    public MsgConfig conf() {
        return MsgIdBFight.FIGHT_TEST_REQ;
    }


    private FightSide getSide(Role role, byte team, int testId) {
        FightTestRow ftr = role.getGame().table.fightTest.base.get(testId);
        if (ftr == null) {
            return null;
        }
        if (StringUtils.isNotBlank(ftr.sideInsCode)) {
            return role.getGame().fight.side.createFightSideByCode(team, ftr.sideInsCode).data;
        } else {
            EcResult<FightSide> r_side = role.getGame().fight.side.createFightSideByRole(team, role, ftr.funcId, ftr.posNum);
            return r_side.data;
        }
    }
}
